<template>
  <BaseDialog :loading="loading" destroy-on-close @confirm="save" @close="close" confirmText="保存" v-model="isShow"
              :title="title">
    <el-form
        ref="formRef"
        :model="state.dataForm"
        :rules="rules"
        label-width="80px"
        @submit="save"
    >
      <el-row>
        <el-col :span="11">
          <!--(1:菜单/2:目录/3:按钮)-->
          <el-form-item label="类型" prop="type">
            <BaseRadioButton @change="typeChangeHandler" dict="auth_type_dict"  v-model="state.dataForm.type"></BaseRadioButton>
          </el-form-item>
        </el-col>
        <el-col :offset="2" :span="11">
          <el-form-item label="上级菜单" prop="pid">
            <SelectMenu ref="selectMenuRef" clearable v-model="state.dataForm.pid"> </SelectMenu>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="11">
          <el-form-item label="标题" prop="menuTitle">
            <el-input clearable placeholder="请输入标题" v-model="state.dataForm.menuTitle"/>
          </el-form-item>
        </el-col>
        <el-col :offset="2" :span="11">
          <el-form-item label="权限标识" prop="authFlag">
            <el-input clearable placeholder="请输入权限标识" v-model="state.dataForm.authFlag"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row v-show="state.dataForm.type === 1">
        <el-col  :span="11">
            <el-form-item label="菜单名称" prop="menuName">
              <el-input clearable placeholder="请输入菜单名称" v-model="state.dataForm.menuName"/>
            </el-form-item>
        </el-col>
        <el-col :offset="2" :span="11">
          <el-form-item label="菜单类型" prop="menuType">
            <BaseRadioButton dict="menu_type_dict"  v-model="state.dataForm.menuType"></BaseRadioButton>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row v-show="state.dataForm.type === 1">
        <el-col :span="11">
          <el-form-item label="文件路径" prop="filePath">
            <el-input clearable placeholder="请输入文件路径" v-model="state.dataForm.filePath"/>
          </el-form-item>
        </el-col>
        <el-col :offset="2" :span="11">
          <el-form-item label="是否固定" prop="affix">
            <el-switch :active-value="1" :inactive-value="2" v-model="state.dataForm.affix"  />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row v-show="[1,2].includes(state.dataForm.type)">
        <el-col  :span="11">
          <el-form-item label="请求路径" prop="requestPath">
            <el-input clearable placeholder="请输入请求路径" v-model="state.dataForm.requestPath"/>
          </el-form-item>
        </el-col>
        <el-col :offset="2" :span="11">
          <el-form-item label="是否隐藏" prop="hidden">
            <el-switch :active-value="1" :inactive-value="2" v-model="state.dataForm.hidden"  />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row v-show="[1,2].includes(state.dataForm.type)">
        <el-col :span="11">
          <el-form-item label="菜单图标" prop="icon">
            <BaseIconSelect class="w-full" v-model="state.dataForm.icon"></BaseIconSelect>
          </el-form-item>
        </el-col>
        <el-col :offset="2" :span="11">
          <el-form-item label="菜单参数" prop="params">
            <el-input clearable placeholder="请输入菜单参数" v-model="state.dataForm.params"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="11">
          <el-form-item label="顺序字段" prop="orderNum">
            <el-input-Number :min="1"  :max="999999999" v-model="state.dataForm.orderNum" />
          </el-form-item>
        </el-col>
        <el-col :offset="2" :span="11">
          <el-form-item label="是否启用" prop="enabled">
            <el-switch :active-value="1" :inactive-value="2" v-model="state.dataForm.enabled"  />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </BaseDialog>
</template>

<script setup lang="ts">

import {nextTick, reactive, ref} from "vue";
import {MenuModel} from "/@/api/system/model/MenuModel";
import {insertMenu, updateMenu} from "/@/api/system/MenuApi";
import SelectMenu from './SelectMenu.vue'

const emit = defineEmits([ 'load'])
const state = reactive({
  dataForm: {
    menuId: '',
    menuTitle: '',
    menuName: '',
    authFlag: '',
    type: 1,
    filePath: '',
    requestPath: '',
    enabled: 1,
    menuType: 1,
    icon: '',
    hidden: 1,
    affix: 1,
    pid: '',
    params: '',
    orderNum: 1,
  } as MenuModel
})
const selectMenuRef = ref()
const formRef = ref()
const loading = ref(false)
const isShow = ref(false)
const title = ref("")
const init = (titleValue: string, data: MenuModel,menus: MenuModel[]) => {
  isShow.value = true

  //判断是否为修改
  if (data && data.menuId) {
    state.dataForm = data
    typeChangeHandler(data.type,true)
  }else {
    //新增
    //初始化上级菜单
    if(data){
      state.dataForm.pid = data.pid
    }else{
      state.dataForm.pid = "0"
    }
    //判断上级菜单类型,设置当前菜单类型
    if([1,3].includes(data.type)){
      state.dataForm.type = 3
      setPidSelectDisabled(3)
      typeChangeHandler(3,true)
    }else{
      setPidSelectDisabled(1)
      typeChangeHandler(1,true)
    }
  }
  //设置菜单标题
  title.value = titleValue
  nextTick(() => {
    selectMenuRef.value.init(menus)
  })
}
/**
 * 保存菜单
 */
const save = async () => {
  await formRef.value.validate()
  loading.value = true
  if(state.dataForm.menuId) {
    await updateMenu(state.dataForm,()=>{
      loading.value = false
    })
  } else {
    await insertMenu(state.dataForm,()=>[
      loading.value = false
    ])
  }
  emit('load')
  close()
}
/**
 * 关闭
 */
const close = () => {
  state.dataForm = {
    menuId: '',
    menuTitle: '',
    menuName: '',
    authFlag: '',
    type: 1,
    filePath: '',
    requestPath: '',
    enabled: 1,
    menuType: 1,
    icon: '',
    hidden: 1,
    affix: 1,
    pid: '',
    params: '',
    orderNum: 1,
  } as MenuModel
  isShow.value = false;
}
/**
 * 变更类型
 * @param value
 */
const typeChangeHandler = (value,isInit: null | boolean) => {
  if(!isInit){
    state.dataForm.pid = "0"
  }
  //设置上级菜单选择禁用
  setPidSelectDisabled(value)
  //设置校验必填字段
  if(1 == value){
    rules.value = {...rulesAuth,...rulesMenu}
  }else if(2 == value){
    rules.value = {...rulesAuth,...rulesCatalog}
  }else {
    rules.value = {...rulesAuth}
  }
  let timer = setTimeout(()=>{
    formRef.value.clearValidate()
  }, 50);

}
/**
 * 设置上级菜单选择禁用
 * @param value
 */
const setPidSelectDisabled = (value)=>{
  //设置上级菜单禁用类型
  if([1,2].includes(value)){
    nextTick(() => {
      //当类型为菜单和目录时，上级菜单只能挂载目录,所以禁用菜单和权限类型
      selectMenuRef.value.setDisableType([1,3])
    })

  }else {
    nextTick(() => {
      //如果类型为权限可以挂在所有节点
      selectMenuRef.value.setDisableType([])
    })

  }
}

defineExpose({init})

const rules = ref(
    {

    }
)
const rulesAuth = {
  menuTitle: [
    { required: true, message: '标题不能为空', trigger: 'blur' },
    { min: 1, max: 64, message: '标题长度为1到64个字符',trigger: 'blur'}
  ],
  authFlag: [
    { required: true, message: '权限标识不能为空', trigger: 'blur' },
    { min: 1, max: 64, message: '权限标识长度为1到64个字符',trigger: 'blur'}
  ],
  pid: [
    { required: true, message: '父菜单不能为空', trigger: 'blur' },
  ]
}
const rulesMenu = {
  menuName: [
    { required: true, message: '菜单名称不能为空', trigger: 'blur' },
    { min: 1, max: 64, message: '菜单名称长度为1到64个字符',trigger: 'blur'}
  ],
  filePath: [
    { required: true, message: '文件路径不能为空', trigger: 'blur' },
    { min: 1, max: 255, message: '文件路径长度为1到255个字符',trigger: 'blur'}
  ],
  requestPath: [
    { required: true, message: '请求不能为空', trigger: 'blur' },
    { min: 1, max: 255, message: '请求路径长度为1到255个字符',trigger: 'blur'}
  ],
  icon: [
    { min: 1, max: 64, message: '菜单图标长度为1到64个字符',trigger: 'blur'}
  ],
  params: [
    { min: 1, max: 255, message: '菜单参数长度为1到255个字符',trigger: 'blur'}
  ],
}
const rulesCatalog = {
  requestPath: [
    { required: true, message: '请求不能为空', trigger: 'blur' },
    { min: 1, max: 255, message: '请求路径长度为1到255个字符',trigger: 'blur'}
  ],
  icon: [
    { min: 1, max: 64, message: '菜单图标长度为1到64个字符',trigger: 'blur'}
  ],
  params: [
    { min: 1, max: 255, message: '菜单参数长度为1到255个字符',trigger: 'blur'}
  ],
}
</script>

<style scoped>

</style>